package alp.starcode.edms.sso.service;

import alp.starcode.edms.framework.base.BaseService;
import alp.starcode.edms.framework.constant.Constant;
import alp.starcode.edms.framework.exception.UserException;
import alp.starcode.edms.sso.model.vo.UserVo;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;

/**
 * 登录管理 业务层
 *
 * @author liwang
 * 2023-08-14 09:18
 **/
@Slf4j
@Service
public class SsoService extends BaseService {

    @Value("${oauth2.get-user-info-url:}")
    private String getUserInfoUrl;

    @Value("${oauth2.logout-url:}")
    private String logoutUrl;

    @Value("${oauth2.login-page-url:}")
    private String loginPageUrl;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 用户登录认证
     *
     * @param username 用户名
     * @param password 密码
     * @return String token
     */
    public String authenticate(String username, String password) {
        // TODO: 实现登录认证逻辑
        return null;
    }

    /**
     * 用户登出
     *
     * @param request 用户请求
     * @return Boolean
     */
    public String logout(HttpServletRequest request) {
        // 获取请求头中的token
        String token = request.getHeader(Constant.TOKEN);
        // 验证token
        if (StringUtils.isBlank(token)) {
            throw new UserException("Token不能为空");
        }
        // 调用认证服务,注销Token有效性
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.setBearerAuth(token);
        // 实现登出逻辑
        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);
        ResponseEntity<String> exchange = restTemplate.exchange(logoutUrl, HttpMethod.DELETE, requestEntity, String.class);
        if(exchange.getStatusCode() == HttpStatus.OK) {
            JSONObject entries = JSONUtil.parseObj(exchange.getBody());
            Integer code = entries.getInt("code");
            if(code == 0) {
                return loginPageUrl;
            } else {
                log.error("调用认证服务code码异常: {}", code);
                throw new UserException("用户登出code码异常");
            }
        } else {
            log.error("调用认证服务状态码异常: {}", exchange.getStatusCode());
            throw new UserException("调用认证服务状态码异常");
        }
    }

    /**
     * 获取用户信息
     *
     * @param request 用户请求
     * @return User user
     */
    public UserVo getUserInfo(HttpServletRequest request) {
        // 获取请求头中的token
        String token = request.getHeader(Constant.TOKEN);
        // 验证token
        if (StringUtils.isBlank(token)) {
            throw new UserException("Token不能为空");
        }
        // 调用认证服务,验证Token有效性
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.setBearerAuth(token);
        // 实现登出逻辑
        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);
        ResponseEntity<String> exchange = restTemplate.exchange(getUserInfoUrl, HttpMethod.GET, requestEntity, String.class);
        try {
            exchange = restTemplate.exchange(getUserInfoUrl, HttpMethod.GET, requestEntity, String.class);
        } catch (Exception e) {
            log.error("调用认证服务异常", e);
            throw new UserException("调用认证服务异常");
        }
        if(exchange.getStatusCode() == HttpStatus.OK) {
            JSONObject entries = JSONUtil.parseObj(exchange.getBody());
            Integer code = entries.getInt("code");
            if (code == 0) {
                JSONObject data = entries.getJSONObject("data");
                JSONObject sysUser = data.getJSONObject("sysUser");
                UserVo userVo = new UserVo();
                userVo.setId(sysUser.getStr("userId"));
                userVo.setUsername(sysUser.getStr("username"));
                userVo.setName(sysUser.getStr("name"));
                return userVo;
            } else {
                log.error("调用认证服务code码异常: {}", code);
                throw new UserException("用户信息查询code码异常");
            }
        } else {
            log.error("调用认证服务状态码异常: {}", exchange.getStatusCode());
            throw new UserException("调用认证服务状态码异常");
        }
    }

} 